package cn.xiaoke.fanxin.类型与限制;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

public class 上下边界 {


    public static void main(String[] args) {

        List<Employee> list1 = new ArrayList<>();
        List<? extends Programmer> list2 = new ArrayList<>();
        List<? super Programmer> list3 = new ArrayList<>();
        List<? extends Backend> list4 = new ArrayList<>();
        List<? super Backend> list5 = new ArrayList<>();


        List<Backend> backends = new ArrayList<>();
        List<Frontend> frontends = new ArrayList<>();
        final Hr hr = new Hr();


        hr.招聘(backends);
        hr.招聘(frontends);

        final Boss boss = new Boss();
        final List<Employee> employeesByType = hr.getEmployeesByType(Employee.class);
        boss.jobCut(employeesByType, new LossJobCutStrategy());
        final List<Programmer> employeesByType2 = hr.getEmployeesByType(Programmer.class);
        boss.jobCut(employeesByType2, new GoBrokeJobCutStrategy());

        final Employee boss1 = new Boss();
        final Programmer programmer = new Programmer();
        List<Boss> list = new ArrayList<>();

        min1(list);
        min2(boss1, programmer);
        Boss[] bosses = {};
        Employee[] employees = {};
        min3(bosses);

    }

    public static <T extends Comparable<? super T>> T min1(List<T> list) {
        return null;
    }

    public static <T extends Comparable<T>> T min2(T... ls) {
        return null;
    }

    public static <T extends Comparable<T>> T min3(T[] ls) {
        return null;
    }


    static class Employee implements Comparable<Employee> {

        int getPerformance() {
            return 0;
        }

        int getSalary() {
            return 0;
        }

        void eat(String food) {
        }

        void work() {
        }

        InterviewInfo show() {
            return null;
        }

        @Override
        public int compareTo(Employee o) {
            return 0;
        }
    }

    static class Boss extends Employee {

        <E extends Employee> void jobCut(List<E> list, JobCutStrategy<? super E> jobCutStrategy) {
            final Iterator<E> iterator = list.iterator();
            while (iterator.hasNext()) {
                final E next = iterator.next();
                if (jobCutStrategy.getPerformance(next)) {
                    iterator.remove();
                }
            }
        }


    }

    static abstract class JobCutStrategy<T extends Employee> {
        abstract boolean getPerformance(T t);
    }

    static class LossJobCutStrategy extends JobCutStrategy<Employee> {
        @Override
        boolean getPerformance(Employee employee) {
            return employee.getPerformance() < 300;
        }
    }

    static class GoBrokeJobCutStrategy extends JobCutStrategy<Programmer> {
        @Override
        boolean getPerformance(Programmer employee) {
            final int asda = employee.getLevel();
            return employee.getSalary() > 20;
        }
    }

    static class Hr extends Employee {
        List<Employee> employees = new ArrayList<>();

        public <T> List<T> getEmployeesByType(Class<T> clazz) {
            return (List<T>) employees.stream().filter(clazz::isInstance).collect(Collectors.toList());
        }

        public void 招聘(List<? extends Employee> employees) {
            for (Employee employee : employees) {

                final InterviewInfo show = employee.show();
            }
        }
    }

    static class Programmer extends Employee {
        int getLevel() {
            return 1;
        }

    }

    static class Architect extends Programmer {

    }

    static class Backend extends Programmer {

    }

    static class Frontend extends Programmer {
    }

    static class PrimaryBackend extends Backend {

    }

    static class MiddleBackend extends Backend {

    }

    static class ExpertBackend extends Backend {

    }

    static class InterviewInfo {
        Integer salary;
        Integer age;
        Integer level;
        Integer score;
    }


}
